package com.app.service.imessage;

import com.app.model.main.UserInfo;
import com.app.model.response.RetCode;
import com.app.model.response.RetStatus;
import com.app.repository.interfaces.ImageMapper;
import com.app.repository.interfaces.UserInfoMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tls.base64_url.base64_url;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.util.Arrays;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

/**
 * Created by Lichaojie on 2017/4/7. It's a beautiful day.
 */
@Service
public class IMService {

    private final Logger logger = Logger.getLogger(IMService.class);

    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;

    public class GenTLSSignatureResult
    {
        public String errMessage;
        public String urlSig;
        public int expireTime;
        public int initTime;
        public GenTLSSignatureResult()
        {
            errMessage = "";
            urlSig = "";
        }
    }

    public class CheckTLSSignatureResult
    {
        public String errMessage;
        public boolean verifyResult;
        public int expireTime;
        public int initTime;
        public CheckTLSSignatureResult()
        {
            errMessage = "";
            verifyResult = false;
        }
    }

    public String doMain(String userId) {

/*
        final long APP_ID = 1400027305l;

        final String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
                "MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQg+bgtmJjZE0rVvg+0vWGC\n" +
                "HNWlYT393wAQ7m4YKri5j9WhRANCAARdBXuSf7LOkXm8pnzugApdOy7JKE+udwvZ\n" +
                "yFWKdeEm4tpL5gz2FESHzsDIEDElH6Z/kJrTDfxocgYb1iHMb9/F\n" +
                "-----END PRIVATE KEY-----\n";

        final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
                "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXQV7kn+yzpF5vKZ87oAKXTsuyShPrncL\n" +
                "2chVinXhJuLaS+YM9hREh87AyBAxJR+mf5Ca0w38aHIGG9YhzG/fxQ==\n" +
                "-----END PUBLIC KEY-----\n";
*/
        final long APP_ID = 1400037242;

        final String PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n" +
                "MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQg/y7n3N8ynJONhGzQR4g+\n" +
                "AfRLiZilIfGJvECRNkWYiWehRANCAASI8XiiAdL1LhFos4rTAyq0JWbaS1pRTc2K\n" +
                "UC/Q8sJyjo9/UDuRRffJLBFwd/K8RWdkXYzwWikSVUQvHUWolR89\n" +
                "-----END PRIVATE KEY-----\n";

        final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" +
                "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiPF4ogHS9S4RaLOK0wMqtCVm2ktaUU3N\n" +
                "ilAv0PLCco6Pf1A7kUX3ySwRcHfyvEVnZF2M8FopElVELx1FqJUfPQ==\n" +
                "-----END PUBLIC KEY-----\n";

        GenTLSSignatureResult result = new GenTLSSignatureResult();
        CheckTLSSignatureResult checkResult;

        try{
            //Use pemfile keys to test
            //String privStr = PRIVATE_KEY;

            //change public pem string to public string
            //String pubStr = PUBLIC_KEY;

            // generate signature
            result = GenTLSSignatureEx(APP_ID, userId, PRIVATE_KEY);
            if (0 == result.urlSig.length()) {
                System.out.println("GenTLSSignatureEx failed: " + result.errMessage);
                return "";
            }

            System.out.println("---\ngenerate sig:\n" + result.urlSig + "\n---\n");

            // check signature
            checkResult = CheckTLSSignatureEx(result.urlSig, APP_ID, userId, PUBLIC_KEY);
            if(!checkResult.verifyResult) {
                System.out.println("CheckTLSSignature failed: " + result.errMessage);
                return "";
            }

            System.out.println("\n---\ncheck sig ok -- expire time " + checkResult.expireTime + " -- init time " + checkResult.initTime + "\n---\n");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        return result.urlSig;
    }

    /**
     * @brief 生成 tls 票据
     * @param expire 有效期，单位是秒，推荐一个月
     * @param strAppid3rd 填写与 sdkAppid 一致字符串形式的值
     * @param skdAppid 应用的 appid
     * @param identifier 用户 id
     * @param accountType 创建应用后在配置页面上展示的 acctype
     * @param privStr 生成 tls 票据使用的私钥内容
     * @return 如果出错，GenTLSSignatureResult 中的 urlSig为空，errMsg 为出错信息，成功返回有效的票据
     * @throws IOException
     */
    @Deprecated
    public GenTLSSignatureResult GenTLSSignature(long expire,
                                                        String strAppid3rd, long skdAppid,
                                                        String identifier, long accountType,
                                                        String privStr ) throws IOException
    {

        GenTLSSignatureResult result = new GenTLSSignatureResult();

        Security.addProvider(new BouncyCastleProvider());
        Reader reader = new CharArrayReader(privStr.toCharArray());
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        PEMParser parser = new PEMParser(reader);
        Object obj = parser.readObject();
        parser.close();
        PrivateKey privKeyStruct = converter.getPrivateKey((PrivateKeyInfo) obj);

        //Create Json string and serialization String
        String jsonString = "{"
                + "\"TLS.account_type\":\"" + accountType +"\","
                +"\"TLS.identifier\":\"" + identifier +"\","
                +"\"TLS.appid_at_3rd\":\"" + strAppid3rd +"\","
                +"\"TLS.sdk_appid\":\"" + skdAppid +"\","
                +"\"TLS.expire_after\":\"" + expire +"\""
                +"}";
        //System.out.println("#jsonString : \n" + jsonString);

        String time = String.valueOf(System.currentTimeMillis()/1000);
        String SerialString =
                "TLS.appid_at_3rd:" + strAppid3rd + "\n" +
                        "TLS.account_type:" + accountType + "\n" +
                        "TLS.identifier:" + identifier + "\n" +
                        "TLS.sdk_appid:" + skdAppid + "\n" +
                        "TLS.time:" + time + "\n" +
                        "TLS.expire_after:" + expire +"\n";


        //System.out.println("#SerialString : \n" + SerialString);
        //System.out.println("#SerialString Hex: \n" + Hex.encodeHexString(SerialString.getBytes()));

        try{
            //Create Signature by SerialString
            Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
            signature.initSign(privKeyStruct);
            signature.update(SerialString.getBytes(Charset.forName("UTF-8")));
            byte[] signatureBytes = signature.sign();

            String sigTLS = Base64.encodeBase64String(signatureBytes);
            //System.out.println("#sigTLS : " + sigTLS);

            //Add TlsSig to jsonString
            JSONObject jsonObject= new JSONObject(jsonString);
            jsonObject.put("TLS.sig", (Object)sigTLS);
            jsonObject.put("TLS.time", (Object)time);
            jsonString = jsonObject.toString();

            // System.out.println("#jsonString : \n" + jsonString);

            //compression
            Deflater compresser = new Deflater();
            compresser.setInput(jsonString.getBytes(Charset.forName("UTF-8")));

            compresser.finish();
            byte [] compressBytes = new byte [512];
            int compressBytesLength = compresser.deflate(compressBytes);
            compresser.end();
            //System.out.println("#compressBytes "+ compressBytesLength+": " + Hex.encodeHexString(Arrays.copyOfRange(compressBytes,0,compressBytesLength)));

            //String userSig = Base64.encodeBase64URLSafeString(Arrays.copyOfRange(compressBytes,0,compressBytesLength));
            String userSig = new String(base64_url.base64EncodeUrl(Arrays.copyOfRange(compressBytes, 0, compressBytesLength)));

            result.urlSig = userSig;
            //System.out.println("urlSig: "+ userSig);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            result.errMessage = "generate usersig failed";
        }

        return result;
    }

    /**
     * @brief 校验 tls 票据
     * @param urlSig 返回 tls 票据
     * @param strAppid3rd 填写与 sdkAppid 一致的字符串形式的值
     * @param skdAppid 应的 appid
     * @param identifier 用户 id
     * @param accountType 创建应用后在配置页面上展示的 acctype
     * @param publicKey 用于校验 tls 票据的公钥内容，但是需要先将公钥文件转换为 java 原生 api 使用的格式，下面是推荐的命令
     *         openssl pkcs8 -topk8 -in ec_key.pem -outform PEM -out p8_priv.pem -nocrypt
     * @return 如果出错 CheckTLSSignatureResult 中的 verifyResult 为 false，错误信息在 errMsg，校验成功为 true
     * @throws DataFormatException
     */
    @Deprecated
    public CheckTLSSignatureResult CheckTLSSignature( String urlSig,
                                                             String strAppid3rd, long skdAppid,
                                                             String identifier, long accountType,
                                                             String publicKey ) throws DataFormatException
    {
        CheckTLSSignatureResult result = new CheckTLSSignatureResult();
        Security.addProvider(new BouncyCastleProvider());

        //DeBaseUrl64 urlSig to json
        Base64 decoder = new Base64();

        //byte [] compressBytes = decoder.decode(urlSig.getBytes());
        byte [] compressBytes = base64_url.base64DecodeUrl(urlSig.getBytes(Charset.forName("UTF-8")));

        //System.out.println("#compressBytes Passing in[" + compressBytes.length + "] " + Hex.encodeHexString(compressBytes));

        //Decompression
        Inflater decompression =  new Inflater();
        decompression.setInput(compressBytes, 0, compressBytes.length);
        byte [] decompressBytes = new byte [1024];
        int decompressLength = decompression.inflate(decompressBytes);
        decompression.end();

        String jsonString = new String(Arrays.copyOfRange(decompressBytes, 0, decompressLength));

        //System.out.println("#Json String passing in : \n" + jsonString);

        //Get TLS.Sig from json
        JSONObject jsonObject= new JSONObject(jsonString);
        String sigTLS = jsonObject.getString("TLS.sig");

        //debase64 TLS.Sig to get serailString
        byte[] signatureBytes = decoder.decode(sigTLS.getBytes(Charset.forName("UTF-8")));

        try{

            String sigTime = jsonObject.getString("TLS.time");
            String sigExpire = jsonObject.getString("TLS.expire_after");

            //checkTime
            //System.out.println("#time check: "+ System.currentTimeMillis()/1000 + "-"
            //+ Long.parseLong(sigTime) + "-" + Long.parseLong(sigExpire));
            if( System.currentTimeMillis()/1000 - Long.parseLong(sigTime) > Long.parseLong(sigExpire))
            {
                result.errMessage = new String("TLS sig is out of date ");
                System.out.println("Timeout");
                return result;
            }

            //Get Serial String from json
            String SerialString =
                    "TLS.appid_at_3rd:" + strAppid3rd + "\n" +
                            "TLS.account_type:" + accountType + "\n" +
                            "TLS.identifier:" + identifier + "\n" +
                            "TLS.sdk_appid:" + skdAppid + "\n" +
                            "TLS.time:" + sigTime + "\n" +
                            "TLS.expire_after:" + sigExpire + "\n";

            //System.out.println("#SerialString : \n" + SerialString);

            Reader reader = new CharArrayReader(publicKey.toCharArray());
            PEMParser  parser = new PEMParser(reader);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
            Object obj = parser.readObject();
            parser.close();
            PublicKey pubKeyStruct  = converter.getPublicKey((SubjectPublicKeyInfo) obj);

            Signature signature = Signature.getInstance("SHA256withECDSA","BC");
            signature.initVerify(pubKeyStruct);
            signature.update(SerialString.getBytes(Charset.forName("UTF-8")));
            boolean bool = signature.verify(signatureBytes);
            //System.out.println("#jdk ecdsa verify : " + bool);
            result.verifyResult = bool;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            result.errMessage = "Failed in checking sig";
        }

        return result;
    }

    /**
     * @brief 生成 tls 票据，精简参数列表，有效期默认为 180 天
     * @param skdAppid 应用的 sdkappid
     * @param identifier 用户 id
     * @param privStr 私钥文件内容
     * @return
     * @throws IOException
     */
    public GenTLSSignatureResult GenTLSSignatureEx(
            long skdAppid,
            String identifier,
            String privStr) throws IOException {
        return GenTLSSignatureEx(skdAppid, identifier, privStr, 3600*24*180);
    }

    /**
     * @brief 生成 tls 票据，精简参数列表
     * @param skdAppid 应用的 sdkappid
     * @param identifier 用户 id
     * @param privStr 私钥文件内容
     * @param expire 有效期，以秒为单位，推荐时长一个月
     * @return
     * @throws IOException
     */
    public GenTLSSignatureResult GenTLSSignatureEx(
            long skdAppid,
            String identifier,
            String privStr,
            long expire) throws IOException {

        GenTLSSignatureResult result = new GenTLSSignatureResult();

        Security.addProvider(new BouncyCastleProvider());
        Reader reader = new CharArrayReader(privStr.toCharArray());
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        PEMParser parser = new PEMParser(reader);
        Object obj = parser.readObject();
        parser.close();
        PrivateKey privKeyStruct = converter.getPrivateKey((PrivateKeyInfo) obj);

        String jsonString = "{"
                + "\"TLS.account_type\":\"" + 0 +"\","
                +"\"TLS.identifier\":\"" + identifier +"\","
                +"\"TLS.appid_at_3rd\":\"" + 0 +"\","
                +"\"TLS.sdk_appid\":\"" + skdAppid +"\","
                +"\"TLS.expire_after\":\"" + expire +"\","
                +"\"TLS.version\": \"201512300000\""
                +"}";

        String time = String.valueOf(System.currentTimeMillis()/1000);
        String SerialString =
                "TLS.appid_at_3rd:" + 0 + "\n" +
                        "TLS.account_type:" + 0 + "\n" +
                        "TLS.identifier:" + identifier + "\n" +
                        "TLS.sdk_appid:" + skdAppid + "\n" +
                        "TLS.time:" + time + "\n" +
                        "TLS.expire_after:" + expire +"\n";

        try {
            //Create Signature by SerialString
            Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
            signature.initSign(privKeyStruct);
            signature.update(SerialString.getBytes(Charset.forName("UTF-8")));
            byte[] signatureBytes = signature.sign();

            String sigTLS = Base64.encodeBase64String(signatureBytes);

            //Add TlsSig to jsonString
            JSONObject jsonObject= new JSONObject(jsonString);
            jsonObject.put("TLS.sig", (Object)sigTLS);
            jsonObject.put("TLS.time", (Object)time);
            jsonString = jsonObject.toString();

            //compression
            Deflater compresser = new Deflater();
            compresser.setInput(jsonString.getBytes(Charset.forName("UTF-8")));

            compresser.finish();
            byte [] compressBytes = new byte [512];
            int compressBytesLength = compresser.deflate(compressBytes);
            compresser.end();
            String userSig = new String(base64_url.base64EncodeUrl(Arrays.copyOfRange(compressBytes,0,compressBytesLength)));

            result.urlSig = userSig;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            result.errMessage = "generate usersig failed";
        }

        return result;
    }

    public CheckTLSSignatureResult CheckTLSSignatureEx(
            String urlSig,
            long sdkAppid,
            String identifier,
            String publicKey ) throws DataFormatException {

        CheckTLSSignatureResult result = new CheckTLSSignatureResult();
        Security.addProvider(new BouncyCastleProvider());

        //DeBaseUrl64 urlSig to json
        Base64 decoder = new Base64();

        byte [] compressBytes = base64_url.base64DecodeUrl(urlSig.getBytes(Charset.forName("UTF-8")));

        //Decompression
        Inflater decompression =  new Inflater();
        decompression.setInput(compressBytes, 0, compressBytes.length);
        byte [] decompressBytes = new byte [1024];
        int decompressLength = decompression.inflate(decompressBytes);
        decompression.end();

        String jsonString = new String(Arrays.copyOfRange(decompressBytes, 0, decompressLength));

        //Get TLS.Sig from json
        JSONObject jsonObject= new JSONObject(jsonString);
        String sigTLS = jsonObject.getString("TLS.sig");

        //debase64 TLS.Sig to get serailString
        byte[] signatureBytes = decoder.decode(sigTLS.getBytes(Charset.forName("UTF-8")));

        try {
            String strSdkAppid = jsonObject.getString("TLS.sdk_appid");
            String sigTime = jsonObject.getString("TLS.time");
            String sigExpire = jsonObject.getString("TLS.expire_after");

            if (Integer.parseInt(strSdkAppid) != sdkAppid)
            {
                result.errMessage = new String(	"sdkappid "
                        + strSdkAppid
                        + " in tls sig not equal sdkappid "
                        + sdkAppid
                        + " in request");
                return result;
            }

            if ( System.currentTimeMillis()/1000 - Long.parseLong(sigTime) > Long.parseLong(sigExpire)) {
                result.errMessage = new String("TLS sig is out of date");
                return result;
            }

            //Get Serial String from json
            String SerialString =
                    "TLS.appid_at_3rd:" + 0 + "\n" +
                            "TLS.account_type:" + 0 + "\n" +
                            "TLS.identifier:" + identifier + "\n" +
                            "TLS.sdk_appid:" + sdkAppid + "\n" +
                            "TLS.time:" + sigTime + "\n" +
                            "TLS.expire_after:" + sigExpire + "\n";

            Reader reader = new CharArrayReader(publicKey.toCharArray());
            PEMParser  parser = new PEMParser(reader);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
            Object obj = parser.readObject();
            parser.close();
            PublicKey pubKeyStruct  = converter.getPublicKey((SubjectPublicKeyInfo) obj);

            Signature signature = Signature.getInstance("SHA256withECDSA","BC");
            signature.initVerify(pubKeyStruct);
            signature.update(SerialString.getBytes(Charset.forName("UTF-8")));
            boolean bool = signature.verify(signatureBytes);
            result.expireTime = Integer.parseInt(sigExpire);
            result.initTime = Integer.parseInt(sigTime);
            result.verifyResult = bool;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            result.errMessage = "Failed in checking sig";
        }

        return result;
    }


    /**
     * 向IM 服务器提交用户信息（包括头像、昵称……）
     * @return
     */
    public boolean setInfo(UserInfo userInfo) throws Exception{
        HttpClient httpClient = new DefaultHttpClient();

        String host = "https://console.tim.qq.com/v4/profile/portrait_set?";
        //usersig=xxx&identifier=admin&sdkappid=88888888&random=99999999&contenttype=json
        String identifier = "admin";
        String usersig = doMain(identifier);
        long sdkappid = 1400037242;
        int random = 1;
        String contenttype = "json";

        String url = host + "usersig=" + usersig + "&"
                + "identifier=" + identifier + "&"
                + "sdkappid=" + sdkappid + "&"
                + "random=" + random + "&"
                + "contenttype=" + contenttype;
        HttpPost httpPost = new HttpPost(url);

        List<JSONObject> jsonObjectList = new ArrayList<>();
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("Tag", "Tag_Profile_IM_Nick");
        jsonObject1.put("Value", userInfo.getNickName());
//        Item item1 = new Item();
//        item1.setTag("Tag_Profile_IM_Nick")
//                .setValue(userInfo.getNickName());
        jsonObjectList.add(jsonObject1);

        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("Tag", "Tag_Profile_IM_Gender");
        jsonObject2.put("Value", userInfo.getGender() == (byte) 0 ? "Gender_Type_Female" : "Gender_Type_Male");
//        Item item2 = new Item();
//        item2.setTag("Tag_Profile_IM_Gender")
//                .setValue(userInfo.getGender() == (byte) 0 ? "Gender_Type_Female" : "Gender_Type_Male");
        jsonObjectList.add(jsonObject2);

        JSONObject jsonObject3 = new JSONObject();
        jsonObject3.put("Tag", "Tag_Profile_IM_AllowType");
        jsonObject3.put("Value", "AllowType_Type_AllowAny");
//        Item item3 = new Item();
//        item3.setTag("Tag_Profile_IM_AllowType")
//                .setValue("AllowType_Type_AllowAny");
        jsonObjectList.add(jsonObject3);

        JSONObject jsonObject4 = new JSONObject();
        jsonObject4.put("Tag", "Tag_Profile_IM_Image");
        jsonObject4.put("Value", userInfo.getAvator() + "");
//        Item item4 = new Item();
//        item4.setTag("Tag_Profile_IM_Image")
//                .setValue(userInfo.getAvator() + "");
        jsonObjectList.add(jsonObject4);
        //jsonObject.put("Tag_Profile_IM_Image",imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin());

        JSONObject json = new JSONObject();
        json.put("From_Account",Long.toString(userInfo.getId()));
        json.put("ProfileItem", jsonObjectList);

        StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");
        System.out.println("request : \n" + json.toString());
        httpPost.setEntity(stringEntity);

        HttpResponse response = httpClient.execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        System.out.println("response : \n" + result.toString());
        logger.info("response : " + result.toString());

        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(result.toString(),Map.class);
        }catch (IOException e){
            e.printStackTrace();
        }
        String actionStatus = (String)paraMap.get("ActionStatus");
        System.out.println("actionStatus : " + actionStatus);

        if(actionStatus.equals("OK")){
            return true;
        }else {
            return false;
        }

    }

    public boolean importInfo(UserInfo userInfo) throws Exception{
        HttpClient httpClient = new DefaultHttpClient();

        String host = "https://console.tim.qq.com/v4/im_open_login_svc/account_import?";
        //usersig=xxx&identifier=admin&sdkappid=88888888&random=99999999&contenttype=json
        String identifier = "admin";
        String usersig = doMain(identifier);
        long sdkappid = 1400037242;
        int random = 1;
        String contenttype = "json";

        String url = host + "usersig=" + usersig + "&"
                + "identifier=" + identifier + "&"
                + "sdkappid=" + sdkappid + "&"
                + "random=" + random + "&"
                + "contenttype=" + contenttype;
        HttpPost httpPost = new HttpPost(url);

        JSONObject json = new JSONObject();
        json.put("Identifier",userInfo.getId() + "");

        StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");
        logger.info("request : \n" + json.toString());
        httpPost.setEntity(stringEntity);

        HttpResponse response = httpClient.execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        System.out.println("response : \n" + result.toString());
        logger.info("response : " + result.toString());

        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(result.toString(),Map.class);
        }catch (IOException e){
            e.printStackTrace();
        }
        String actionStatus = (String)paraMap.get("ActionStatus");
        System.out.println("actionStatus : " + actionStatus);

        if(actionStatus.equals("OK")){
            return true;
        }else {
            return false;
        }
    }

    public boolean sendMessage(long from_account,long to_account) throws IOException{
        HttpClient httpClient = new DefaultHttpClient();

        String host = "https://console.tim.qq.com/v4/openim/sendmsg?";

        String identifier = "admin";
        String usersig = doMain(identifier);
        long sdkappid = 1400037242;
        int random = 1;
        String contenttype = "json";

        String url = host + "usersig=" + usersig + "&"
                + "identifier=" + identifier + "&"
                + "sdkappid=" + sdkappid + "&"
                + "random=" + random + "&"
                + "contenttype=" + contenttype;
        HttpPost httpPost = new HttpPost(url);

        JSONObject text = new JSONObject();
        text.put("Text","(＾０＾)，我是源小源，欢迎使用源来~\n" +
                "从现在开始，与大家一起学习、交流与成长，踏上这段收获之旅吧！\n" +
                "\n" +
                "如果在使用过程中遇到任何问题，欢迎进入【我】-【设置】-【意见反馈】随时提出你的意见，我们会重视每一个用户的反馈！\n" +
                "如果还有其他问题，欢迎随时私信我，小源将努力为你解答！\n" +
                "\n" +
                "可私信、不可调戏的\n" +
                "源来团队队花-源小源\n");

        JSONObject msgBody = new JSONObject();
        msgBody.put("MsgType","TIMTextElem");
        msgBody.put("MsgContent",text);

        JSONObject msgBodyArray[] = new JSONObject[1];
        msgBodyArray[0] = msgBody;

        JSONObject responseBody = new JSONObject();
        responseBody.put("SyncOtherMachine",1);
//        UserInfo fromUser = userInfoMapper.selectByPrimaryKey(from_account);
//        UserInfo toUser = userInfoMapper.selectByPrimaryKey(to_account);
        responseBody.put("From_Account",Long.toString(from_account));
        responseBody.put("To_Account",Long.toString(to_account));
        responseBody.put("MsgRandom",1287657);
        responseBody.put("MsgTimeStamp", System.currentTimeMillis() / 1000);
        responseBody.put("MsgBody", msgBodyArray);

        StringEntity stringEntity = new StringEntity(responseBody.toString(),"UTF-8");
        logger.info("request : \n" + responseBody.toString());
        System.out.println("request : \n" + responseBody.toString());
        httpPost.setEntity(stringEntity);

        HttpResponse response = httpClient.execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        System.out.println("response : \n" + result.toString());
        logger.info("response : " + result.toString());

        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(result.toString(),Map.class);
        }catch (IOException e){
            e.printStackTrace();
        }
        String actionStatus = (String)paraMap.get("ActionStatus");
        System.out.println("actionStatus : " + actionStatus);

        if(actionStatus.equals("OK")){
            return true;
        }else {
            return false;
        }

    }

    public RetStatus getInfo(long userId) throws Exception{
        HttpClient httpClient = new DefaultHttpClient();

        String host = "https://console.tim.qq.com/v4/profile/portrait_get?";
        //usersig=xxx&identifier=admin&sdkappid=88888888&random=99999999&contenttype=json
        String identifier = "admin";
        String usersig = doMain(identifier);
        long sdkappid = 1400037242;
        int random = 1;
        String contenttype = "json";

        String url = host + "usersig=" + usersig + "&"
                + "identifier=" + identifier + "&"
                + "sdkappid=" + sdkappid + "&"
                + "random=" + random + "&"
                + "contenttype=" + contenttype;
        HttpPost httpPost = new HttpPost(url);

        List<String> idList = new ArrayList<>();
        idList.add(Long.toString(userId));
        List<String> tagList = new ArrayList<>();
        tagList.add("Tag_Profile_IM_Nick");
        tagList.add("Tag_Profile_IM_Gender");
        tagList.add("Tag_Profile_IM_Image");

        JSONObject json = new JSONObject();
        json.put("To_Account",idList);
        json.put("TagList",tagList);

        StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");
        logger.info("request : \n" + json.toString());
        httpPost.setEntity(stringEntity);

        HttpResponse response = httpClient.execute(httpPost);
        int code = response.getStatusLine().getStatusCode();
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }
        System.out.println("response : \n" + result.toString());
        logger.info("response : " + result.toString());

        RetStatus retStatus = new RetStatus();
        retStatus.setCode(100)
                .setMessage(RetCode.getMessage(100))
                .setBody(result);

        return retStatus;
    }

    public class Item{
        public String Tag;
        public String Value;

        public String getTag() {
            return Tag;
        }

        public Item setTag(String tag) {
            Tag = tag;
            return this;
        }

        public String getValue() {
            return Value;
        }

        public Item setValue(String value) {
            Value = value;
            return this;
        }
    }
}
